/*
 * @Description:
 * @Version: 1.0
 * @Autor: lzc
 * @Date: 2021-11-16 10:32:50
 * @LastEditors: lzc
 * @LastEditTime: 2021-11-17 13:33:51
 */
/* Includes ------------------------------------------------------------------*/
#include "fsm.h"
/*
                                    +-------------------------------------------------------------+
                                    |                       Event 5      Sleep                    |
                                    |                                                             |
                                    |                                                             |
                                    | +--------------------------------------------+              |
                                    | |           Event 5      Sleep               |              |
                                    | |                                            |              |
                                    | |                                            |              |
                                    | |                                            |              |
                                    | |                                            |              |
            +---------+  PowerOn  +-v-v-----+  IO IRQ    +---------+  Cal Com  +---+-----+        |
            |  Start  +---------> |  Sleep  +----------> |   Init  +---------> |  CAL    |        |
            +---------+ Event 1   +-^-^-----+  Event 2   +---+-+---+  Event 6  +---------+        |
                State 1             | |State 2               | | State 3         State 7          |
                                    | |                      | |                                  |
                                    | |                      | |                                  |
                                    | |                      | |                                  |
                                    | |                      | |                                  |
                                    | |            Event 3   | |  Event 4                         |
                                    | |Event 5   +-----------+ +-------+                          |
                                    | |Sleep     | Red Com             |OPM Com                   |
                                    | |          |                     |                          |
                                    | |          |           Event 4   |                          |
                                    | |          |           OPM Com   |                          |
                                    | |          |              +---+  |                          |
                                    | |          | State 4      |   |  |   State 5                |
                                    | |      +---v-----+        | +-+--v----+                     |
                                    | +------+  Red    |        | |   OPM   +---------------------+
                                    |        +----+----+        | +-^---+---+
                                    |             |             |   |   |
                                    |             |             |   |   |
                                    |             |             +---+   |
                                    |             |Event 4              |
                                    |             |OPM Com              |
                                    |             |                     |
                                    |             |      Event 4        |Event 3
                                    |             |      OPM Com        |Red Com
                                    |             |      +----+         |
                                    |             |      |    |         |
                                    |             |    +-+----v--+      |
                                    |             +--->| Red_OPM <------+
                                    |                  +-----+---+
                                    |                       |  State 6
                                    |                       |
                                    |                       |
                                    |  Event 5      Sleep   |
                                    +-----------------------+
 */
StateTransform *findTrans(StateMachine *pSM,  const EventID evt)
{
    int i;
    for (i = 0; i < pSM->transNum; i++)
    {
        if ((pSM->transform[i].curState == pSM->state) && (pSM->transform[i].eventId == evt))
        {
            return &pSM->transform[i];
        }
    }
    return NULL;
}


void runStateMachine(StateMachine *pSM, const EventID evt)
{
    StateTransform *pTrans;
    pTrans = findTrans(pSM, evt);
    if (pTrans == NULL)
    {
#if DEBUG
        printf( "CurState= %d Do not process enent: %d\r\n", pSM->state, evt);
#endif
        return;
    }
    pSM->state = pTrans->nextState;
    Action act = pTrans->action;
    if (act == NULL)
    {
#if DEBUG
        printf( "change state to %d. No action\r\n", pSM->state);
#endif
        return;
    }
    act(&evt);
}

char Init_Sleep(const EventID *ID)
{
    printf("State Init_Sleep\r\n");
    return 0;
}


extern char Sleep(const EventID *ID);
extern char Ready_Ack(const EventID *ID);
extern char Red_Light(const EventID *ID);
extern char OPM_Read(const EventID *ID);
extern char OPM_Red_On(const EventID *ID);
extern char Cal(const EventID *ID);
StateTransform stateTran[] =
{
    {state_1, event_1, state_2, Sleep},             // 状态1 通过 事件1 跳转 状态 2 执行 初始化就进入睡眠 指令
    {state_2, event_2, state_3, Ready_Ack},         // 状态2 通过 事件2 跳转 状态 3 执行 应答状态 指令
    {state_3, event_3, state_4, Red_Light},         // 状态3 通过 事件3 跳转 状态 4 执行 红光 指令
    {state_3, event_4, state_5, OPM_Read},          // 状态3 通过 事件4 跳转 状态 5 执行 OPM 指令
    {state_3, event_6, state_7, Cal},               // 状态3 通过 事件6 跳转 状态 7 执行 Cal 指令
    {state_4, event_4, state_6, OPM_Red_On},        // 状态4 通过 事件4 跳转 状态 6 执行 RED+OPM 指令
    {state_4, event_5, state_2, Sleep},             // 状态4 通过 事件5 跳转 状态 2 执行 Sleep 指令
    {state_5, event_3, state_6, OPM_Red_On},        // 状态5 通过 事件3 跳转 状态 6 执行 RED+OPM 指令
    {state_5, event_4, state_5, OPM_Read},          // 状态5 通过 事件4 跳转 状态 5 执行 OPM 指令(循环)
    {state_5, event_5, state_2, Sleep},             // 状态5 通过 事件5 跳转 状态 2 执行 Sleep 指令
    {state_6, event_5, state_2, Sleep},             // 状态6 通过 事件5 跳转 状态 2 执行 Sleep 指令
    {state_6, event_4, state_6, OPM_Red_On},        // 状态6 通过 事件4 跳转 状态 6 执行 RED+OPM 指令
    {state_7, event_5, state_2, Sleep}              // 状态7 通过 事件5 跳转 状态 2 执行 Sleep 指令
};

int run(void)
{
    StateMachine stateMachine;
    stateMachine.state = state_1;
    stateMachine.transNum = 13;
    stateMachine.transform = stateTran;

    runStateMachine(&stateMachine, event_1);
    runStateMachine(&stateMachine, event_2);
    runStateMachine(&stateMachine, event_6);
    runStateMachine(&stateMachine, event_5);
    return 0;
}
